package com.agua.enturno.util;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.Period;

import java.util.ArrayList;
import java.util.List;


public class JodaTimeUtils {

	private static JodaTimeUtils instance = new JodaTimeUtils();
	private BiMap<Integer, String> daysOfWeek = HashBiMap.create(7);
	
	/*-------------------------------------- Singleton -------------------------------------*/

	private JodaTimeUtils() {
		initDaysOfWeek();
	}

	public static JodaTimeUtils getInstance() {
		return instance;
	}

	/*--------------------------------------------------------------------------------------*/
	/*------------------------------------ Public methods ----------------------------------*/

	public Interval moveInterval(Interval intervalo, Period periodo) {
		return new Interval(intervalo.getStart().plus(periodo), intervalo.getEnd().plus(periodo));
	}
	
	public DateTime getDateTimeEnSemanaActual(DayOfWeekTime dayOfWeekTime) {
		
		DateTime dateTime = new DateTime().
				withDayOfWeek(dayOfWeekTime.getDayOfWeek()).
				withTime(dayOfWeekTime.getHourOfDay(), dayOfWeekTime.getMinuteOfHour(), 0, 0);
		
		if ( dateTime.isBeforeNow() ) {
			dateTime = dateTime.plusWeeks(1);
		}
		
		return dateTime;
	}

	public Interval getIntervaloEnSemanaActual(DayOfWeekTime diaYHoraDeInicio, DayOfWeekTime diaYHoraDeFin) {
		
		DateTime fechaDelDiaDeLaSemanaDeInicio = getDateTimeEnSemanaActual(diaYHoraDeInicio);
		DateTime fechaDelDiaDeLaSemanaDeFin = getDateTimeEnSemanaActual(diaYHoraDeFin);
		
		if (fechaDelDiaDeLaSemanaDeFin.isBefore(fechaDelDiaDeLaSemanaDeInicio))
			fechaDelDiaDeLaSemanaDeFin = fechaDelDiaDeLaSemanaDeFin.plusWeeks(1);
		
		return new Interval(fechaDelDiaDeLaSemanaDeInicio, fechaDelDiaDeLaSemanaDeFin);
	}
	
	public Duration toDuration(DayOfWeekTime diaYHoraDeInicio, DayOfWeekTime diaYHoraDeFin) {
		return getIntervaloEnSemanaActual(diaYHoraDeInicio, diaYHoraDeFin).toDuration();
	}
	
	public String getTextDayOfWeek(Integer intDayOfWeek) {
		return daysOfWeek.get(intDayOfWeek);
	}
	
	public Integer getIntDayOfWeek(String textDayOfWeek) {
		return daysOfWeek.inverse().get(textDayOfWeek);
	}
	
	public List<String> getDaysOfWeek() {
		return new ArrayList<String>(daysOfWeek.values());
	}

	/*--------------------------------------------------------------------------------------*/
	/*----------------------------------- Private methods ----------------------------------*/

	private void initDaysOfWeek() {
		
		daysOfWeek.put(1, "lunes");
		daysOfWeek.put(2, "martes");
		daysOfWeek.put(3, "miércoles");
		daysOfWeek.put(4, "jueves");
		daysOfWeek.put(5, "viernes");
		daysOfWeek.put(6, "sábado");
		daysOfWeek.put(7, "domingo");
	}

	/*--------------------------------------------------------------------------------------*/

}
